/*
    This file is part of open-wars <http://code.google.com/p/open-wars/>.

    open-wars is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    open-wars is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with open-wars.  If not, see <http://www.gnu.org/licenses/>.
*/

#include <opengl-font.h>

int nextPower(int val){
    int x = 1;
    while(x<val){
        x <<= 1;
    }
    return x;
}

GLFont loadFont(STRING filepath, int height){

    GLFont temp = new _GLFont();
    FT_Library lib;
    FT_Face face;
    FT_Glyph glyph;
    FT_Bitmap* bitmap;
    FT_BitmapGlyph* bitglyph;
    int w, h, xpos, ypos;
    unsigned char i;
    GLubyte* buffer;
    float texpropx, texpropy;

    glGenTextures(128, temp->textures);
    temp->displaylist = glGenLists(128);

    FT_Init_FreeType(&lib);
    FT_New_Face(lib, filepath.c_str(), 0, &face);
    FT_Set_Char_Size(face, height << 6, height << 6, 96, 96);

    for (i=0;i<128;i++){
        // get bitmap
        FT_Load_Glyph(face, FT_Get_Char_Index(face, i), FT_LOAD_DEFAULT);
        FT_Get_Glyph(face->glyph, &glyph);
        FT_Glyph_To_Bitmap(&glyph, ft_render_mode_normal, 0, 1);
        bitglyph = (FT_BitmapGlyph*)&glyph;
        bitmap = &((FT_BitmapGlyph)glyph)->bitmap;
        w= 1;
        while(w<bitmap->width)
            w *= 2;
        h= 1;
        while(h<bitmap->rows)
            h *= 2;
        // make bitmap
        buffer = (GLubyte*)calloc(sizeof(GLubyte)*2*w*h, 1);
        for (ypos=0;ypos<bitmap->rows;ypos++){
            for (xpos=0;xpos<bitmap->width;xpos++){
                buffer[2*(xpos+ypos*w)] = bitmap->buffer[xpos+ypos*bitmap->width];
                buffer[2*(xpos+ypos*w)+1] = bitmap->buffer[xpos+ypos*bitmap->width];
            }
        }

        glBindTexture(GL_TEXTURE_2D, temp->textures[i]);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);

        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, buffer);

        // make display list (for nicely formatted text)
        glPushMatrix();
        glNewList(temp->displaylist+i, GL_COMPILE);
        glBindTexture(GL_TEXTURE_2D, temp->textures[i]);
        glPushMatrix();
        glTranslatef((*bitglyph)->left, bitmap->rows - (*bitglyph)->top-bitmap->rows, 0);
        // proportions of the texture that are the font (not padding)
        texpropx = (float)bitmap->width / (float)w;
        texpropy = (float)bitmap->rows / (float)h;

        glBegin(GL_QUADS);
            glTexCoord2f(0.0f, texpropy);       glVertex3f(0.0f, bitmap->rows, 0.0f);
            glTexCoord2f(0.0f, 0.0f);           glVertex3f(0.0f, 0.0f, 0.0f);
            glTexCoord2f(texpropx, 0.0f);       glVertex3f(bitmap->width, 0.0f, 0.0f);
            glTexCoord2f(texpropx, texpropy);   glVertex3f(bitmap->width, bitmap->rows, 0.0f);
        glEnd();
        glPopMatrix();
        glTranslatef(face->glyph->advance.x >> 6, 0, 0);
        glEndList();
        glPopMatrix();

        free(buffer);
    }

    FT_Done_Face(face);

    FT_Done_FreeType(lib);
    
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);

    return temp;
}

int printFont(GLFont temp, STRING text){
    glListBase(temp->displaylist);
    glCallLists(strlen(text.c_str()), GL_UNSIGNED_BYTE, text.c_str());
    return 0;
}

int deleteFont(GLFont temp){
    glDeleteTextures(128, temp->textures);
    glDeleteLists(temp->displaylist, 128);
    free(temp);
    return 0;
}
